
triple buffering:
https://www.anandtech.com/show/2794/2
opengl has a good triple buffer system
directx has a shitty triple buffer system that adds input lag
	(it seems to have a good one too, but nobody uses it/people say it's worthless/who knows. they're probably just idiots everywhere)
	it also has Nvidia Fast Sync, which came in Maxwell, which is 2014.

https://www.blurbusters.com/blur-busters-lagless-raster-follower-algorithm-for-emulator-developers/ beam racing, Windows, seems to get exact beam locations.
https://forums.blurbusters.com/viewforum.php?f=22
https://forums.blurbusters.com/viewtopic.php?f=7&t=4064 monitor cable
https://www.vsynctester.com/howtocomputevsync.html
PID controller is not appropriate, chosen frame start time doesn't affect the rendering time in a meaningful way
scanline racing: you need to do most of the vertex shader/physics/networking work before starting to render the first pixel, so the frame time advantage is just the pixel shader.
	if the screen is divided into 10 horizontal strips, then the optimal result is a gain of 9/10 the pixel shader runtime.
	scanline racing has the disadvantage that it no longer works with things like DWM, or KDE's triple buffering. all other vsync-like systems work perfectly.
http://doc-ok.org/?p=1057 gets Linux vsync, but only on X. no Wayland info. also, he hasn't actually done it, it's just theoretical
	GLX_SGI_video_sync()
G-sync: needs to run 3 fps below max. theoretically it's perfect at that point?

why doesn't Windows have tearing? a reddit post claims that DWM on Windows > 8.1 has automatic triple buffering: https://www.reddit.com/r/pcgaming/comments/3cpbqr/windows_10_forced_vsync/csxqibw/
however another reddit post by a Microsoft employee claims that DWM has no triple buffering: https://www.reddit.com/r/Windows10/comments/645ukf/windows_10_cu_fullscreen_optimizations/dghii4m/

KDE has vsync on by default: https://userbase.kde.org/Desktop_Effects_Performance#Use_VSync
Linux vsync is broken on most compositors: https://www.reddit.com/r/emulation/comments/4uyyza/eli5_compositing_desktop_window_manager_triple/d5u4g32/

in Firefox/Chrome, vsyncs are missable. because you don't get vsync timepoints, you get frame-signal timepoints.
	the cost of a missing frame is bounded above by the frame time cost. note that missing frames are caused by variations in render time plus external interference, which happen frequently. delayed timepoints are caused only by external interference. that means delaying the timepoint is way harder than missed frames, and thus a delayed timepoint of 1 frame should be penalized way, way harder than a missed frame.
but more importantly, these timepoints are also sometimes faked backwards, so our algorithm doesn't work on it.

missing periods: vblank timepoints still appear when the renderer is minimized. in fact, they don't seem tied to rendering endpoints at all.
so the only issue is gsync.

possible note: heavy load may mean that long frames have extra-delayed periods.
note that latency is only important for frames with inputs. if we measure frame times only for frames without input, and then have spikes on the frames with input, that is of no use.
note that in the program, we often will have approximate info on which vblanks are expected to be delayed, since we know the frame render time. that means if a period/phase pair skips a frame that's in the middle of rendering, that skip is free. but this won't happen for all skipped frames, such as if the user alt-tabs. and the frame render time is also delayed.
note: clock drift means that there's no need to hold all the timepoints forever.
	"He tested his own laptop against an expensive precision clock and found his computer had drifted off by 15 milliseconds within two hours. “This is typical behavior,” he said."
"NTP also has difficulty maintaining accuracy in virtualized cloud environments, often for mysterious reasons. “Getting accurate time out of virtual machines is something that has plagued all of the virtual machine providers"
	that's an easy way to determine a VM.
clock skew: "It is not unusual for an RTC to gain or lose several seconds or even minutes a day, and some of them -- while still considered to be operating correctly by the manufacturer-- can be off by an hour or more after a week or two without correction."
"500 PPM mean the clock is off by about 43 seconds per day. Only poor old mechanical wristwatches are worse."

Linux:
https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/45
fast swaps: https://github.com/glfw/glfw/pull/1406
	GLFW with triangle under mouse. relies on Wayland extension, presentation-time

simple algorithm.
first pass: 1024 timepoints. rate = (last - first) / 1024.
second pass: if the difference between two timepoints is > 1.5, then it counts as two. but if the difference dips below 0, then keep track of that to undo twos.
basically: you see 1.6, so add a two and 0.6 to the sum. then you see 0.3, so the sum becomes -0.1 and remove a two.
well, basically: split it into blocks, where the distance between blocks is always > 1. then, extend each block as far as it needs to go so that its average time is large enough. we don't round times within a block
	it's "spreading" any too-small timepoints to its neighbors.
	what's the limit on spreading? if something is >2x timepoints, then spreading shouldn't take care of its nonsense.
	if it's like 1.6 1 1 0.4, then the 0.4 shouldn't be able to spread to the 1.6. but 1.6 1 0.4, maybe yes. 1.8 1 0.2, probably no.
then do a simple pivot, so that you are locked on two timepoints on the two sides
then move down by the order statistic.


OpenGL's glQueryCounter(id, GL_TIMESTAMP) uses the GPU clock, which skews.
so comparisons must be GPU-to-GPU, not to the CPU.



https://www.anthropicstudios.com/2022/01/13/asking-windows-nicely/#trick-1-asking-windows-nicely
	turning off power throttling

https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/65
	they have the best mode! "VSync_relaxed"
	same as EXT_swap_control_tear